<template>
  <el-dialog
    :title="title"
    :visible.sync="dialogVisible"
    :close-on-click-modal="false"
    width="30%"
    :before-close="handleClose"
  >
    <el-form ref="ruleForm" :model="formData" :rules="rules" :inline="true" label-width="80px" style="margin-left: 15%" label-position="right" size="small">
      <el-form-item label="是否显示" prop="is_show">
        <el-radio-group v-model="formData.is_show" :disabled="isEdit === 'view'">
          <el-radio label="true">显示</el-radio>
          <el-radio label="false">不显示</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item v-if="formData.is_show === 'true'" label="菜单图标" prop="icon">
        <el-popover
          :disabled="isEdit === 'view'"
          placement="bottom-start"
          width="460"
          trigger="click"
          @show="$refs['iconSelect'].reset()"
        >
          <IconSelect ref="iconSelect" :disabled="isEdit === 'view'" @selected="selected" />
          <el-input slot="reference" v-model="formData.icon" placeholder="点击选择图标" readonly :disabled="isEdit === 'view'">
            <svg-icon v-if="formData.icon" slot="prefix" :icon-class="formData.icon" clearable style="height: 32px;width: 16px;" />
            <i v-else slot="prefix" class="el-icon-search el-input__icon" />
          </el-input>
        </el-popover>
      </el-form-item>
      <el-form-item label="菜单名称" prop="name">
        <el-input v-model="formData.name" placeholder="请输入名称" clearable :disabled="isEdit === 'view'" />
      </el-form-item>
      <el-form-item label="菜单排序" prop="sort">
        <el-input v-model.number="formData.sort" placeholder="请输入序号（越小越靠前）" clearable :disabled="isEdit === 'view'" />
      </el-form-item>
      <el-form-item label="内部菜单" prop="is_frame">
        <el-radio-group v-model="formData.is_frame" :disabled="isEdit === 'view'">
          <el-radio label="false">是</el-radio>
          <el-radio label="true">否</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item v-if="formData.is_frame === 'false'" label="组件路径">
        <el-input v-model="formData.component" placeholder="请输入组件路径" clearable :disabled="isEdit === 'view'" />
      </el-form-item>

      <el-form-item label="链接地址">
        <el-input v-model="formData.path" placeholder="请输入菜单路径" clearable :disabled="isEdit === 'view'" />
      </el-form-item>
      <el-form-item label="父级菜单" prop="pid">
        <el-cascader
          v-model="formData.pid"
          :disabled="isEdit === 'view'"
          :options="treeMenu"
          :props="{
            expandTrigger: 'hover',
            checkStrictly: true,
            label: 'label',
            value: 'id',
            children: 'children'}"
          placeholder="请选择父级菜单"
          :show-all-levels="false"
          filterable
          clearable
          @expand-change="isTree"
        />
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="handleClose" v-text="isBtnCloseTitle" />
      <el-button v-show="isEdit !== 'view'" type="primary" @click="SubmitForm" v-text="isBtnConfTitle" />
    </span>
  </el-dialog>
</template>

<script>
import IconSelect from '../../../../components/IconSelect'
import { treeMenu, viewMenu, addMenu, editMenu, checkMenusName, checkMenusSort, checkMenusPid } from '@/api/menu'

export default {
  components: { IconSelect },
  // 接收父组件传递过来的值
  props: {
    vdialog: {
      type: Boolean,
      default: false
    },
    vtitle: {
      type: String,
      default: ''
    },
    visedit: {
      type: String,
      default: ''
    },
    vformid: {
      // 接收父组件传过来的ID
      type: Number,
      default: 0
    }
  },
  data() {
    const rulesCheckMenuName = (rule, value, callback) => {
      if (this.formData.name === this.formDataBak.name) {
        callback()
      }
      checkMenusName({ name: this.formData.name }).then((res) => {
        if (res.exists && res.code === 200) {
          callback(new Error(res.message))
          return
        } else {
          callback()
        }
      })
    }
    const rulesCheckMenuSort = (rule, value, callback) => {
      if (this.formData.sort === this.formDataBak.sort) {
        callback()
      }
      checkMenusSort({ sort: this.formData.sort }).then((res) => {
        if (res.exists && res.code === 200) {
          callback(new Error(res.message))
          return
        } else {
          callback()
        }
      })
    }
    const rulesCheckMenuPid = (rule, value, callback) => {
      if (this.formData.pid === null || this.formData.pid.length === 0) {
        this.rulesPid = ''
      } else {
        this.rulesPid = this.formData.pid.pop()
      }
      checkMenusPid({ name: this.formData.name, pid: this.rulesPid }).then((res) => {
        if (res.exists && res.code === 200) {
          callback(new Error(res.message))
          return
        } else {
          callback()
        }
      })
    }
    return {
      // rulesPid 联级选择器校验附属属性
      rulesPid: '',
      // 控制弹出框的显示与隐藏
      dialogVisible: false,
      title: '',
      isBtnCloseTitle: '',
      isBtnConfTitle: '',
      formData: { name: '', sort: 999, path: '', component: '', is_show: 'true', is_frame: 'false', pid: [], icon: '' },
      isEdit: '',
      formId: '',
      formDataBak: '',
      treeMenu: [],
      // rules 表单前验证
      rules: {
        is_show: [
          { required: true, message: '是否在导航栏显示', trigger: 'blur' }
        ],
        name: [
          { required: true, message: '请输入名称', trigger: 'blur' },
          { validator: rulesCheckMenuName, trigger: 'blur' }
        ],
        sort: [
          { required: true, message: '请输入序号', trigger: 'blur', type: 'number' },
          { validator: rulesCheckMenuSort, trigger: 'blur' }
        ],
        is_frame: [
          { required: true, message: '请选择菜单类型', trigger: 'blur' }
        ],
        pid: [
          { required: false, message: '请选择父级菜单', trigger: 'blur' },
          { validator: rulesCheckMenuPid, trigger: 'blur' }
        ]
      }
    }
  },
  watch: {
    // 监听 父组件传递过来的props内的值并改变/赋值
    vdialog() {
      // dialogVisible 弹框的显示与隐藏
      this.dialogVisible = this.vdialog
      if (this.dialogVisible) {
        // formid 数据ID
        this.formid = this.vformid
        // isEdit 表单状态
        this.isEdit = this.visedit
        // title 弹框的标题
        this.title = this.vtitle
        // isTree 获取目录树数据
        this.isTree()
        // 状态判断
        if (this.isEdit === 'view') {
          this.isBtnCloseTitle = '关闭'
          this.viewForm()
        } else if (this.isEdit === 'add') {
          this.isBtnCloseTitle = '取消'
          this.isBtnConfTitle = '新增'
        } else if (this.isEdit === 'edit') {
          this.isBtnCloseTitle = '取消'
          this.isBtnConfTitle = '编辑'
          this.viewForm()
        }
      }
    }
  },
  created() {
    this.isTree()
  },
  methods: {
    viewForm() {
      viewMenu(this.formid).then(res => {
        this.formDataBak = JSON.parse(JSON.stringify(res.data))
        this.formData.name = res.data.name
        this.formData.sort = res.data.sort
        this.formData.path = res.data.path
        this.formData.component = res.data.component
        this.formData.pid = res.data.pid
        this.formData.icon = res.data.icon
        // radio 无法动态赋值，原因（类型不一致） string
        this.formData.is_show = String(res.data.is_show)
        this.formData.is_frame = String(res.data.is_frame)
      })
    },
    SubmitForm() {
      // 表单验证并新增/编辑
      this.$refs['ruleForm'].validate((valid) => {
        if (valid) {
          // 判断目录树是否有数据，有则截取数值 (this.formData.pid[1] 这里改成取最后一个值)
          if (this.formData.pid) {
            this.formData.pid = this.rulesPid
          }
          if (this.isEdit === 'add') {
            this.addForm()
          } else if (this.isEdit === 'edit') {
            this.editForm()
          } else {
            this.$notify.warning({
              type: 'warning',
              title: '警告',
              message: '表单非法操作',
              showClose: true,
              duration: 0
            })
          }
        }
      })
    },
    addForm() {
      addMenu(this.formData).then((res) => {
        this.$notify.success({
          type: 'success',
          title: '成功',
          message: res.message,
          showClose: true,
          duration: 5 * 1000
        })
        this.isEditStatus()
        // $parent 子组件调用父组件方法
        this.$parent.getList()
      })
    },
    editForm() {
      editMenu(this.formid, this.formData).then((res) => {
        this.$notify.success({
          type: 'success',
          title: '成功',
          message: res.message,
          showClose: true,
          duration: 5 * 1000
        })
        this.isEditStatus()
        // $parent 子组件调用父组件方法
        this.$parent.getList()
      })
    },
    // 弹出框关闭后的函数
    handleClose(done) {
      // 子组件调用父组件方法，并传递参数 this.$emit('父组件的方法', '传递的参数')
      if (this.isEdit === 'view') {
        this.isEditStatus()
      } else {
        if (this.formData.username) {
          this.$confirm('确认取消/关闭？')
            .then(_ => {
              this.isEditStatus()
              done()
            })
            .catch(_ => {})
        } else {
          this.isEditStatus()
        }
      }
    },
    isEditStatus() {
      // this.$refs['form表单里面的ref值'].resetFields()
      this.$refs['ruleForm'].resetFields()
      this.formData = { name: '', sort: 999, path: '', component: '', is_show: 'true', is_frame: 'false', pid: [], icon: '' }
      this.$emit('changeShow', 'false', 0)
    },
    // 弹出框关闭后的函数
    // cascade 级联选择器 目录树
    isTree() {
      treeMenu().then((res) => {
        this.treeMenu = res.data
        this.setDisable(1, this.treeMenu, 4)
      })
    },
    setDisable(count, data, maxNum) {
      if (count > maxNum) {
        data.forEach(v => {
          v.disabled = true
        })
      } else {
        data.forEach(v => {
          if (v.children && v.children.length) {
            count++
            this.setDisable(count, v.children, maxNum)
          }
        })
      }
    },
    // cascade 级联选择器 目录树
    // 图标库
    selected(name) {
      this.formData.icon = name
    }
    // 图标库
  }
}
</script>
